package com.lovelyj.trip_by_train.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.lovelyj.trip_by_train.dto.DailyTrainDto;
import com.lovelyj.trip_by_train.entity.*;
import com.lovelyj.trip_by_train.mapper.DailyRemainTicketMapper;
import com.lovelyj.trip_by_train.mapper.DailyTrainMapper;
import com.lovelyj.trip_by_train.mapper.TrainMapper;
import com.lovelyj.trip_by_train.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class DailyTrainServiceImpl extends ServiceImpl<DailyTrainMapper, DailyTrain> implements DailyTrainService {


    @Autowired
    private ArriveService arriveService;

    @Autowired
    private DailyTrainMapper dailyTrainMapper;

    @Autowired
    private DailySeatService dailySeatService;

    @Autowired
    private DailyRemainTicketService dailyRemainTicketService;

    @Autowired
    private CoachService coachService;


    @Override
    public Page<DailyTrainDto> selectDailyTrainDtoList(Integer page , LocalDate date, String trainNum, String startStation, String endStation){
        Page<DailyTrainDto> pageInfo=new Page<>(page,10);
        MPJLambdaWrapper<DailyTrain> wrapper=new MPJLambdaWrapper<>();
        wrapper.selectAll(DailyTrain.class);
        wrapper.select(Train::getStartStation).select(Train::getEndStation)
                        .select(Train::getStartTime).select(Train::getEndTime).select(Train::getDateDiff);
        wrapper.leftJoin(Train.class,Train::getTrainNum,DailyTrain::getTrainNum);
        wrapper.eq(trainNum!=null,DailyTrain::getTrainNum,trainNum);
        wrapper.eq(date!=null,DailyTrain::getDate,date);
        wrapper.like(startStation!=null,Train::getStartStation,startStation);
        wrapper.like(endStation!=null,Train::getEndStation,endStation);

        return dailyTrainMapper.selectJoinPage(pageInfo, DailyTrainDto.class, wrapper);
    }

    @Transactional
    @Override
    public void saveWithSeatAndTickets(DailyTrain dailyTrain){
        log.info("saveWithSeatAndTickets"+dailyTrain.getTrainNum());
        LocalDate localDate = dailyTrain.getDate();
        String trainNum = dailyTrain.getTrainNum();
        LambdaQueryWrapper<Arrive> arriveLambdaQueryWrapper = new LambdaQueryWrapper<>();
        arriveLambdaQueryWrapper.eq(Arrive::getTrainNum,trainNum);
        arriveLambdaQueryWrapper.orderByAsc(Arrive::getDistance);
        List<Arrive> arrives=new ArrayList<>();
        arrives=arriveService.list(arriveLambdaQueryWrapper);
        int arriveNum=arrives.size();
        StringBuilder status= new StringBuilder();
        for(int i=1;i<arriveNum;i++){
            status.append("0");
        }
        LambdaQueryWrapper<Coach> coachWrapper=new LambdaQueryWrapper<>();
        coachWrapper.eq(Coach::getTrainNum,trainNum);
        List<Coach> coachList=coachService.list(coachWrapper);
        int seatClass0 = 0,seatClass1=0,seatClass2=0,seatClass3=0;
        for(Coach coach:coachList){
            String trainNum1 = coach.getTrainNum();
            String coachNum = coach.getCoachNum();
            Integer row=coach.getSeatRowNumber();
            Integer col=coach.getSeatColNumber();
            for(int r=1;r<=row;r++){
                for(int c=1;c<=col;c++){
                DailySeat seat=new DailySeat();
                seat.setTravelDate(localDate);
                seat.setTrainNum(trainNum1);
                seat.setCoachNum(coachNum);
                seat.setSeatCol(c);
                seat.setSeatRow(r);
                seat.setStatus(status.toString());
                dailySeatService.save(seat);
                }
            }
            if(coach.getCoachClass()==0){
                seatClass0+=coach.getSeatNumber();
            }else if(coach.getCoachClass()==1){
                seatClass1+=coach.getSeatNumber();
            }else if(coach.getCoachClass()==2){
                seatClass2+=coach.getSeatNumber();
            }else if(coach.getCoachClass()==3){
                seatClass3+=coach.getSeatNumber();
            }
        }
        for(int i=0;i<arriveNum-1;i++){
            String startStation=arrives.get(i).getStation();
            for(int j=i+1;j<arriveNum;j++){
                String endStation=arrives.get(j).getStation();
                DailyRemainTicket dailyRemainTicket=new DailyRemainTicket();
                dailyRemainTicket.setTrainNum(trainNum);
                dailyRemainTicket.setStartStation(startStation);
                dailyRemainTicket.setEndStation(endStation);
                dailyRemainTicket.setDate(localDate);
                LocalDate localDate1 = localDate.plusDays(arrives.get(i).getDepartureDay()-arrives.get(i).getArriveDay());
                LocalDateTime localDateTime1 = LocalDateTime.of(localDate1,arrives.get(i).getDepartureTime());
                LocalDateTime localDateTime2 = LocalDateTime.of(localDate1,arrives.get(j).getArriveTime());
                dailyRemainTicket.setStartTime(localDateTime1);
                dailyRemainTicket.setEndTime(localDateTime2);
                dailyRemainTicket.setDistance(arrives.get(j).getDistance()-arrives.get(i).getDistance());
                dailyRemainTicket.setRemainClass0(seatClass0);
                dailyRemainTicket.setRemainClass1(seatClass1);
                dailyRemainTicket.setRemainClass2(seatClass2);
                dailyRemainTicket.setRemainClass3(seatClass3);
                dailyRemainTicketService.save(dailyRemainTicket);
            }
        }
        this.save(dailyTrain);
    }


    @Override
    @Transactional
    public void removeWithSeatAndTickets(Long id){

        DailyTrain dailyTrain=this.getById(id);
        String trainNum=dailyTrain.getTrainNum();
        LocalDate localDate=dailyTrain.getDate();
        LambdaQueryWrapper<DailySeat> dailySeatWrapper=new LambdaQueryWrapper<>();
        dailySeatWrapper.eq(DailySeat::getTrainNum,trainNum);
        dailySeatWrapper.eq(DailySeat::getTravelDate,localDate);
        dailySeatService.remove(dailySeatWrapper);
        LambdaQueryWrapper<DailyRemainTicket> dailyRemainTicketMapperLambdaQueryWrapper=new LambdaQueryWrapper<>();
        dailyRemainTicketMapperLambdaQueryWrapper.eq(DailyRemainTicket::getTrainNum,trainNum);
        dailyRemainTicketMapperLambdaQueryWrapper.eq(DailyRemainTicket::getDate,localDate);
        dailyRemainTicketService.remove(dailyRemainTicketMapperLambdaQueryWrapper);

        this.removeById(id);
    }

}
